/*
 * TilesContainer.fx
 *
 * Created on 29.7.2009, 23:27:
 */

package com.gpsbuddy.objects;

import javafx.scene.input.MouseEvent;

import javafx.scene.Node;
import javafx.scene.CustomNode;


import com.gpsbuddy.utils.TilesUtils;
import javafx.scene.layout.Flow;
import javafx.scene.layout.LayoutInfo;
import javafx.geometry.HPos;

import javafx.util.Math;


/**
 * @author jonycus
 */

public class TilesContainer extends CustomNode {
        public var zoom: Integer = 0 on replace {group.content = loadImages();};

        public var tilesMultip:Integer = 1;

        public var Xtiles: Integer = 4*tilesMultip;
        public var Ytiles: Integer = 4*tilesMultip;

        public var width: Number = bind Xtiles*256;
        public var height: Number = bind Ytiles*256;

        public var sceneWidth: Number = bind scene.width;
        public var sceneHeight: Number = bind scene.height;

        public var lon: Double;
        public var lat: Double;

        var zeroX = bind TilesUtils.getXTile(lon, zoom);
        var zeroY = bind TilesUtils.getYTile(lat, zoom);

        var sx:Number = 0.0;
        var sy:Number = 0.0;

        var xScale:Number = bind 360/(Math.pow(2,zoom)*256);
        var yScale:Number = bind 170.1022/(Math.pow(2,zoom)*256);

        override var layoutX = bind sceneWidth / 2 - width / 2;
        override var layoutY = bind sceneHeight / 2 - height / 2;

        public var group: Flow = Flow {
            width: bind width;
            height: bind height;
            translateX: sceneWidth / 2 - width / 2;
            translateY: sceneHeight / 2 - height / 2;
            hgap: 0;
            vgap: 0;
            hpos: HPos.CENTER;
            content: [
                loadImages()
            ]
            layoutInfo: LayoutInfo {

            }

        }

        override public function create() : Node {
            group.layoutX = 0;
            group.layoutY = 0;
            //println(zeroX);
            //println(zeroY);
            return group
        }

        override var onMouseWheelMoved = function(e: MouseEvent ):Void {
                zoom = TilesUtils.updateZoom(zoom, e.wheelRotation);
            }

          var offsetX: Number;
          var offsetY: Number;

          public var onMove: function (evt: MouseEvent): Void;

          override def onMousePressed = function (evt: MouseEvent): Void {
            offsetX = translateX - evt.sceneX;
            offsetY = translateY - evt.sceneY;
          }

          var leftBorder = (sceneWidth - width)/2;

          var tlx;
          var tly;

          override def onMouseDragged = function (evt: MouseEvent): Void
          {
            tlx = evt.dragAnchorX + evt.dragX + offsetX;
            tly = evt.dragAnchorY + evt.dragY + offsetY;
            //if (tlx<257 and tlx>-width+sceneWidth+256 and tly<257 and tly>-height+sceneHeight+256){
                translateX = evt.dragAnchorX + evt.dragX + offsetX;
                translateY = evt.dragAnchorY + evt.dragY + offsetY;
                onMove(evt);
            //}
            if (tlx>257) tlx = 256;
            if (tlx<width-sceneWidth-256) tlx =-width+sceneWidth+256+1;
            if (tly>257) tly = 256;
            if (tly<height-sceneHeight-256) tly =-height+sceneHeight+256+1;
          }

          override def onMouseReleased = function (evt: MouseEvent) : Void {
                  sx = sx+evt.dragX;
                  sy = sy+evt.dragY;
                  if (sx>256 or sy>256 or sx <-256 or sy <-256) {
                      lat = lat + sy*yScale;
                      lon = lon - sx*xScale;
                      group.content = loadImages();
                      translateX = translateX - sx;
                      translateY = translateY - sy;
                      sx = 0.0;
                      sy = 0.0;
                      println("xScale {xScale}, yScale {yScale}");
                      println("dragX {evt.dragX}, dragY  {evt.dragY}");
                      println("lat {lat}, lon {lon}");
                  }
          }


        function loadImages():Node[]{
                var startX:Integer = 0;
                var endX: Integer = Xtiles-1;
                var startY:Integer = 0;
                var endY: Integer = Ytiles-1;

                if (zeroX mod 2 == 0){
                    startX = zeroX-2*tilesMultip;
                    endX = zeroX+2*tilesMultip-1;
                } else {
                    startX = zeroX-2*tilesMultip;
                    endX = zeroX+2*tilesMultip-1;
                }

                if (zeroY mod 2 == 0){
                    startY = zeroY-2*tilesMultip;
                    endY = zeroY+2*tilesMultip-1;
                } else {
                    startY = zeroY-2*tilesMultip;
                    endY = zeroY+2*tilesMultip-1;
                }

                //println("zeroX {zeroX}, zeroY {zeroY}, multip {tilesMultip}");

            for (i in [startY..endY]){//calculateVisibleXTiles()
                for (j in [startX..endX]){//calculateVisibleYTiles()){
                    TileImageView {
                        tileX: j;
                        tileY: i;
                        zoom: zoom;
                        cache: true;
                    }
                }
            }
        }
}
